using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Xml;
using System.Drawing;
using System.IO;
using System.Diagnostics;

namespace PocketLibrary.Image
{
    public enum SingaporeItemType
    {
        SingaporeGallery,
        SingaporeImage,
    }

    public class Singapore : IService
    {
        public event UploadProgressHandler OnUploadProgress;
        public event UploadProgressHandler OnDownloadProgress;

        private string sgUrl;

        public string SingaporeUrl
        {
            get { return sgUrl; }
            set
            {
                comm.Url = value;
                sgUrl = value;
            }
        }

        private string dataPath;

        public string DataPath
        {
            get { return dataPath; }
            set { dataPath = value; }
        }

        string currentgallery = "";
        public string SelectedGallery
        {
            get { return currentgallery; }
            set { currentgallery = value; }
        }

        string galleryname = "";

        public string GalleryName
        {
            get
            {
                return galleryname;
            }
            set
            {
                galleryname = value;
            }
        }

        string _username = "";
        string _userpassword = "";
        public string UserName
        {
            set
            {
                _username = value;
            }
            get
            {
                return _username;
            }
        }

        public string Password
        {
            set
            {
                _userpassword = HelperUtils.MD5String(value);
            }
            get { return _userpassword; }
        }

        protected XmlDocument sendXmlDoc = new XmlDocument();
        protected XmlDocument rcvXmlDoc = new XmlDocument();
        bool uploading = false;
        bool downloading = false;
        bool requesting = false;

        string imagename = "";
        public string DownloadImageName
        {
            set { imagename = value; }
            get { return imagename; }
        }

        string uploadname = "";
        public string UploadImageName
        {
            set { uploadname = value; }
            get { return uploadname; }
        }

        public Dictionary<string, SingaporeItemType> SingaporeItems = new Dictionary<string, SingaporeItemType>();

        XMLRPCCommunication comm;

        public Singapore()
        {
            comm = new XMLRPCCommunication(this.SingaporeUrl);
            comm.UseStringBuilder = true;

        }

        #region api functions


        //private void SendReceiveXml()
        //{
        //    if (!requesting)
        //    {
        //        requesting = true;
        //        try
        //        {
        //            rcvXmlDoc = new XmlDocument();
        //            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(SingaporeUrl);

        //            req.Method = "POST";
        //            req.UserAgent = "TaskuBlogi 1.0";
        //            req.ContentType = "text/xml";

        //            byte[] data = Encoding.ASCII.GetBytes(sendXmlDoc.InnerXml);
        //            req.ContentLength = data.Length;


        //            //Stream newstream = req.GetRequestStream();
        //            //newstream.Write(data, 0, data.Length);
        //            //newstream.Close();

        //            int j = 1;
        //            int uploadBit = Math.Max(data.Length / 100, 50 * 1024);
        //            int uploadSoFar = 0;
        //            Stream reqStream = req.GetRequestStream();

        //            for (int i = 0; i < data.Length; i = i + uploadBit)
        //            {
        //                int toUpload = Math.Min(uploadBit, data.Length - i);
        //                uploadSoFar += toUpload;

        //                reqStream.Write(data, i, toUpload);

        //                if ((OnUploadProgress != null) && ((j++) % 5 == 0 || uploadSoFar == data.Length))
        //                {
        //                    OnUploadProgress(this, new UploadProgressEventArgs(i + toUpload, data.Length, uploadSoFar == data.Length));
        //                }
        //            }
        //            reqStream.Close();
        //            j = 1;
        //            StringBuilder sbb = new StringBuilder();
        //            HttpWebResponse res = (HttpWebResponse)req.GetResponse();

        //            uploadSoFar = 0;
        //            Stream resStream = res.GetResponseStream();
        //            byte[] resData = new byte[res.ContentLength];
        //            for (int i = 0; i < resData.Length; i = i + uploadBit)
        //            {
        //                int toUpload = Math.Min(uploadBit, resData.Length - i);
        //                uploadSoFar += toUpload;

        //                resStream.Read(resData, i, toUpload);

        //                if ((OnDownloadProgress != null) && ((j++) % 5 == 0 || uploadSoFar == resData.Length))
        //                {
        //                    OnDownloadProgress(this, new UploadProgressEventArgs(i + toUpload, resData.Length, uploadSoFar == resData.Length));
        //                }
        //            }

        //            /*
        //            using (StreamReader sr = new StreamReader(restream))
        //            {
        //                while (sr.Peek() != -1)
        //                {
        //                    sbb.Append(sr.ReadToEnd());
        //                }
        //            }
        //            /**/
        //            resStream.Close();

        //            string responseBody = Encoding.ASCII.GetString(resData, 0, resData.Length);

        //            rcvXmlDoc.LoadXml(responseBody);
        //        }
        //        catch (WebException ex)
        //        {
        //            Console.WriteLine(ex.Message);
        //        }
        //        catch (XmlException ex)
        //        {
        //            Console.WriteLine(ex.Message);
        //        }
        //        catch (Exception ex)
        //        {
        //            Debug.WriteLine(ex.Message, "Singapore.SendReceiveXml");
        //        }
        //        requesting = false;
        //    }
        //    else
        //    {
        //        UploadComplete(false);
        //    }
        //}

        public void getGallery()
        {

            SingaporeItems.Clear();

            StringBuilder sb = new StringBuilder();
            sb.Append("<?xml version=\"1.0\" encoding=\"utf-8\" ?>");
            sb.Append("<singapore>");
            sb.Append("<action>sg.getGallery</action>");
            sb.Append("<params>");
            sb.Append("<username>" + _username + "</username>");
            sb.Append("<password>" + _userpassword + "</password>");
            sb.Append("<getgallery>" + currentgallery + "</getgallery>");
            sb.Append("</params>");
            sb.Append("</singapore>");

            comm.UploadStringBuilder = sb;
            comm.SendReceive();
            rcvXmlDoc.LoadXml(comm.Response);

            Debug.WriteLine(rcvXmlDoc.InnerXml);

            XmlNodeList galleries = rcvXmlDoc.GetElementsByTagName("gallery");
            for (int i = 0; i < galleries.Count; i++)
            {

                SingaporeItems.Add(galleries[i].InnerText, SingaporeItemType.SingaporeGallery);

            }

            XmlNodeList images = rcvXmlDoc.GetElementsByTagName("image");
            for (int i = 0; i < images.Count; i++)
            {
                SingaporeItems.Add(images[i].InnerText, SingaporeItemType.SingaporeImage);
            }
        }

        public void getImage()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("<?xml version=\"1.0\" encoding=\"utf-8\" ?>");
            sb.Append("<singapore>");
            sb.Append("<action>sg.getImage</action>");
            sb.Append("<params>");
            sb.Append("<username>" + _username + "</username>");
            sb.Append("<password>" + _userpassword + "</password>");
            sb.Append("<getimage><gallery>" + currentgallery + "</gallery><image>" + imagename + "</image>");
            sb.Append("</getimage>");
            sb.Append("</params>");
            sb.Append("</singapore>");

            comm.UploadStringBuilder = sb;
            comm.SendReceive();
            rcvXmlDoc.LoadXml(comm.Response);

            XmlNode base64data = rcvXmlDoc.SelectSingleNode("descendant::data/base64");

            using (FileStream fs = new FileStream(this.DataPath + imagename, FileMode.Create, FileAccess.Write, FileShare.Write))
            using (BinaryWriter bw = new BinaryWriter(fs))
            {
                bw.Write(Convert.FromBase64String(base64data.InnerText));
            }
            //DownloadComplete();
            //MemoryStream ms = new MemoryStream(Convert.FromBase64String(base64data.InnerText));
        }

        public Bitmap getThumbnail()
        {

            StringBuilder sb = new StringBuilder();
            sb.Append("<?xml version=\"1.0\" encoding=\"utf-8\" ?>");
            sb.Append("<singapore>");
            sb.Append("<action>sg.getImage</action>");
            sb.Append("<params>");
            sb.Append("<username>" + _username + "</username>");
            sb.Append("<password>" + _userpassword + "</password>");
            sb.Append("<getimage><gallery>" + currentgallery + "</gallery><thumb>" + imagename + "</thumb>");
            sb.Append("</getimage>");
            sb.Append("</params>");
            sb.Append("</singapore>");
            comm.UploadStringBuilder = sb;
            comm.SendReceive();
            rcvXmlDoc.LoadXml(comm.Response);
            XmlNode base64data = rcvXmlDoc.SelectSingleNode("descendant::data/base64");
            if (base64data != null && base64data.InnerText != null)
            {
                MemoryStream ms = new MemoryStream(Convert.FromBase64String(base64data.InnerText));
                //DownloadComplete();
                return new Bitmap(ms);
            }
            return null;
        }

        public void putImage()
        {
            putImage(uploadname);
        }

        public void putImage(string filename)
        {
            if (!uploading)
            {
                uploading = true;
                FileInfo fi = new FileInfo(filename);

                byte[] fbuffer = new byte[fi.Length];

                using (FileStream fs = new FileStream(filename, FileMode.Open))
                using (BinaryReader br = new BinaryReader(fs))
                {
                    br.Read(fbuffer, 0, fbuffer.Length);
                }
                string filecontents = Convert.ToBase64String(fbuffer, 0, fbuffer.Length);

                StringBuilder sb = new StringBuilder();
                sb.Append("<?xml version=\"1.0\" encoding=\"utf-8\" ?>");
                sb.Append("<singapore>");
                sb.Append("<action>sg.putImage</action>");
                sb.Append("<params>");
                sb.Append("<username>" + _username + "</username>");
                sb.Append("<password>" + _userpassword + "</password>");
                sb.Append("<putimage>");
                sb.Append("<gallery>" + currentgallery + "</gallery><filename>" + fi.Name + "</filename>");
                sb.Append("<data>" + filecontents + "</data>");
                sb.Append("</putimage>");
                sb.Append("</params>");
                sb.Append("</singapore>");
                comm.UploadStringBuilder = sb;
                comm.SendReceive();
                //getGallery();

                uploading = false;
            }
        }

        public void putGallery()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("<?xml version=\"1.0\" encoding=\"utf-8\" ?>");
            sb.Append("<singapore>");
            sb.Append("<action>sg.putGallery</action>");
            sb.Append("<params>");
            sb.Append("<username>" + _username + "</username>");
            sb.Append("<password>" + _userpassword + "</password>");
            sb.Append("<putgallery>");
            sb.Append("<parent>" + currentgallery + "</parent>");
            sb.Append("<name>" + galleryname + "</name>");
            sb.Append("</putgallery>");
            sb.Append("</params>");
            sb.Append("</singapore>");

            comm.UploadStringBuilder = sb;
            comm.SendReceive();

            getGallery();
        }

        public void resetIndex()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("<?xml version=\"1.0\" encoding=\"utf-8\" ?>");
            sb.Append("<singapore>");
            sb.Append("<action>sg.resetIndex</action>");
            sb.Append("<params>");
            sb.Append("<username>" + _username + "</username>");
            sb.Append("<password>" + _userpassword + "</password>");
            sb.Append("<resetindex>" + currentgallery + "</resetindex>");
            sb.Append("</params>");
            sb.Append("</singapore>");
            comm.UploadStringBuilder = sb;
            comm.SendReceive();
            getGallery();
        }
        #endregion

        #region IService Members

        public ServiceType ServiceType
        {
            get { return ServiceType.ImageGallery; }
        }

        #endregion
    }
}
